﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Timers;
using System.IO;
using System.Threading;
using System.Diagnostics;
using CDSBDemandControl.Model;
using CDSBDemandControl.Configuration;

namespace CDSBDemandControlService
{
    public class ClassePrincipal
    {
        #region Properties

        System.Timers.Timer DailyTimer;
        System.Timers.Timer RegularTimer;
        DiscriminatorDemandService DemandService;
        string WIOutOfDateXMLPath;
        string WIPendingXMLPath;
        string WIWithCodeReview;
        string AllWIPeriodXMLPath;
        string AllWIGeraLista;
        string WIScenariosAndTasksXMLPath;
        string BugsLastMonth;
        string PrevisaoAlocacao;
        string SolicitacoesSites;
        string ManagementTeamTasks;
        bool stillRunning;
        bool writingFiles;

        #endregion

        public ClassePrincipal()
        {
            //Nunca colocar nada no construtor por questão de performance do Start do Serviço
        }

        /// <summary>
        /// Inicializa o Service.
        /// Seta o caminho para cada XML, instancia a classe de serviço e seta os timers.
        /// </summary>
        private void Initialize()
        {
            DemandService = new DiscriminatorDemandService();

            stillRunning = true;
            writingFiles = false;

            WIPendingXMLPath = ConfigManager.GetWIPendingXMLPath();
            AllWIPeriodXMLPath = ConfigManager.GetAllWIPeriodXMLPath();
            WIOutOfDateXMLPath = ConfigManager.GetWIOutOfDateXMLPath();
            WIWithCodeReview = ConfigManager.GetWIWithCodeReviewXMLPath();
            AllWIGeraLista = ConfigManager.GetWIGeraDispXMLPath();
            BugsLastMonth = ConfigManager.GetBugsLastMonthXMLPath();
            PrevisaoAlocacao = ConfigManager.GetPrevisaoAlocacaoXMLPath();
            SolicitacoesSites = ConfigManager.GetSolicitacoesSitesXMLPath();
            ManagementTeamTasks = ConfigManager.GetManagementTeamTasksXMLPath();
            WIScenariosAndTasksXMLPath = ConfigManager.GetWIScenariosAndTasksXMLPath();

            RegularTimer = new System.Timers.Timer(ConfigManager.GetMinutesToRefresh() * 60000);
            DailyTimer = new System.Timers.Timer(86400000);

            RegularTimer.Elapsed +=new ElapsedEventHandler(RegularTimer_Elapsed);
            DailyTimer.Elapsed += new ElapsedEventHandler(DailyTimer_Elapsed);

            MontaArquivos(0);
            MontaArquivos(1);

            RegularTimer.Start();
            DailyTimer.Start();

        }

        
        
        void DailyTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            DailyTimer.Enabled = false;
            MontaArquivos(1);
            DailyTimer.Enabled = true;
        }        

        void RegularTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            RegularTimer.Enabled = false;
            MontaArquivos(0);
            RegularTimer.Enabled = true;
        }

        /// <summary>
        /// Se receber o parâmetro 0, monta os XMLs de demandas pendêntes e atrasadas.
        /// Se receber o parâmetro 1, monta o XML de todas as demandas desenvolvidas pela área.
        /// </summary>
        /// <param name="whichFile">int</param>
        private void MontaArquivos(int whichFile)
        {
            if  (stillRunning)
            {
                try
                {
                    writingFiles = true;

                    // 0 monta arquivos de WI pendentes e atrasados
                    if (whichFile == 0)
                    {
                        DemandCollection WorkItemsOutOfDate = DemandService.ListWorkItemsOutOfDate();
                        DemandService.CreateFileofWorkItems(WIOutOfDateXMLPath, WorkItemsOutOfDate);
                        WorkItemsOutOfDate.Clear();
                        WorkItemsOutOfDate = null;

                        DemandCollection WorkItemsPending = DemandService.ListWorkItemsPending();
                        DemandService.CreateFileofWorkItems(WIPendingXMLPath, WorkItemsPending);
                        WorkItemsPending.Clear();
                        WorkItemsPending = null;

                        DemandCollection WorkItemsWithCodeReview = DemandService.ListWorkItemsWhoReturnsCodeReview();
                        DemandService.CreateFileofWorkItems(WIWithCodeReview, WorkItemsWithCodeReview);
                        WorkItemsWithCodeReview.Clear();
                        WorkItemsWithCodeReview = null;

                        DemandCollection WorkItemsGeraDisp = DemandService.ListaGeracaoDisponibilidade();
                        DemandService.CreateFileofWorkItems(AllWIGeraLista, WorkItemsGeraDisp);
                        WorkItemsGeraDisp.Clear();
                        WorkItemsGeraDisp = null;

                        DemandCollection GeraBugsLastMonth = DemandService.GeraBugsLastMonth();
                        DemandService.CreateFileofWorkItems(BugsLastMonth, GeraBugsLastMonth);
                        GeraBugsLastMonth.Clear();
                        GeraBugsLastMonth = null;

                        DemandCollection GeraPrevisaoAlocacao = DemandService.GeraPrevisaoAlocacao();
                        DemandService.CreateFileofWorkItems(PrevisaoAlocacao, GeraPrevisaoAlocacao);
                        GeraPrevisaoAlocacao.Clear();
                        GeraPrevisaoAlocacao = null;

                        DemandCollection GeraSolicitacoesSites = DemandService.GeraSolicitacoesSites();
                        DemandService.CreateFileofWorkItems(SolicitacoesSites, GeraSolicitacoesSites);
                        GeraSolicitacoesSites.Clear();
                        GeraSolicitacoesSites = null;

                        DemandCollection GeraManagementTeamTasks = DemandService.GeraManagementTeamTasks();                        
                        DemandService.CreateFileofWorkItems(ManagementTeamTasks, GeraManagementTeamTasks);
                        GeraManagementTeamTasks.Clear();
                        GeraManagementTeamTasks = null;

                        List<ScenarioModel> ScenariosAndTasks = DemandService.ListScenariosAndTasks();
                        DemandService.CreateFileofWorkItems(WIScenariosAndTasksXMLPath, ScenariosAndTasks);
                        ScenariosAndTasks.Clear();
                        ScenariosAndTasks = null;

                    }
                    // 1 monta arquivos com todos os WI.
                    else if (whichFile == 1)
                    {
                        DemandCollection WorkItems = DemandService.ListAllWorkItemsPeriod();
                        DemandService.CreateFileofWorkItems(AllWIPeriodXMLPath, WorkItems);

                        WorkItems.Clear();
                        WorkItems = null;
                    }
                }
                catch (Exception err)
                {
                    EventLog.WriteEntry("CDSBDemandControlService", err.StackTrace, EventLogEntryType.Error, 1);
                }

                writingFiles = false;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public void Run()
        {
            Initialize();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="disposing"></param>
        public void Dispose(bool disposing)
        {
            // Tem que ser a primeira linha do dispose pois o Timer.Stop dispara o evento novamente.
            stillRunning = false;

            // Aguarda escrever os últimos arquivos.
            while (writingFiles) { Thread.Sleep(5); }
            
            RegularTimer.Dispose();
            DailyTimer.Dispose();
            DemandService.Disposing();
        }
    }
}
